#include "main.h"
#include "neai_flash.h"

#define n_bytes  392

uint32_t save_addr = 0x0803f000U;	//ai知识库保存在flash起始地址， page126
uint32_t ram_addr = 0x2000A000;		//ai知识库对应在ram内的地址

uint32_t neaiSize = 386;			//ai知识库的大小，单位字节
//const uint8_t n_bytes = 208;

uint8_t writeflashBuff[n_bytes] = { 0 };	//缓存ai知识库数组，大小是8的整数，可以按8个字节写入flash
uint64_t writeflasData[n_bytes / 8] = { 0 };	//写入flash数据，需要64bit（双字）格式，

static void uint8ToUint64() {
	for (int i = 0; i < (n_bytes / 8); i++) {
		for (int j = 0; j < 8; j++)
			writeflasData[i] |= (uint64_t) writeflashBuff[j + i * 8] << (j * 8);
	}
}

// 保存模型知识库到flash
void save_neai(void) {
	uint32_t pageError;
	FLASH_EraseInitTypeDef reaseflash;	//定义删除结构体
	HAL_StatusTypeDef status;   //定义状态结构体
	//结构体初始化
	reaseflash.TypeErase = FLASH_TYPEERASE_PAGES; //按页删除
	reaseflash.Banks = FLASH_BANK_1;
	reaseflash.Page = 126; //删除页的编号，bank1的倒数第2页，对应地址 0x0803F000
	reaseflash.NbPages = 1; //待删除的页数

	//	从内存取出ai知识库数数据
	memcpy(writeflashBuff, (uint8_t*) ram_addr, neaiSize);
	//	将8bit数组转为64bit数组
	uint8ToUint64();

	//删除操作，解锁-->删除-->上锁
	HAL_FLASH_Unlock(); //先解锁
	status = HAL_FLASHEx_Erase(&reaseflash, &pageError); //删除页
	HAL_FLASH_Lock(); //上锁
	if (status != HAL_OK) {
		;
	} //如果删除失败处理

	//写入操作，解锁-->写入-->上锁
	HAL_FLASH_Unlock(); //解锁
	for (int i = 0; i < (n_bytes / 8); i++) {
		//	每次写入一个64bit数据
		HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, save_addr + i * 8,
				writeflasData[i]);
	}

	HAL_FLASH_Lock();
}

// 从flash恢复到ram
void restore_neai(void) {
	memcpy((void*) ram_addr, (uint8_t*) save_addr, neaiSize);
}


void flash_write(uint32_t addr, uint8_t *buff, int buf_len) {
	int i = 0;
	/* 解锁FLASH */
	HAL_FLASH_Unlock();

	/* 对FLASH烧写 */
	for (i = 0; i < buf_len; i += 8) {
		HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, addr + i,
				*(uint64_t*) (buff + i));
	}

	/* 上锁FLASH */
	HAL_FLASH_Lock();
}


void flash_read(uint32_t addr, uint8_t *buff, int buf_len) {
	uint32_t i;
	for (i = 0; i < buf_len; i++) {
		buff[i] = *(__IO uint8_t*) (addr + i);
	}
}
/*
 * neai_flash.c
 *
 *  Created on: Mar 13, 2024
 *      Author: lye21
 */

